package k8s

import (
	"context"
	"fmt"
	"time"

	"gitee.com/hexug/go-tools/common/validate"
	"gitee.com/hexug/go-tools/logger"
	corev1 "k8s.io/api/core/v1"
	k8serrs "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/json"
)

func (g *implK8s) CreateService(c context.Context, req *CreateServiceRequest) (err error) {
	start := time.Now()
	defer func() {
		logger.L().Infof("elapsed K8SAPI_CreateService:%v", time.Since(start))
	}()
	if err := validate.V().Struct(req); err != nil {
		logger.L().Errorf("参数校验失败:%v", err)
		return fmt.Errorf("参数校验失败:%v", err)
	}
	service := &corev1.Service{}
	if err = json.Unmarshal([]byte(req.ServiceJson), service); err != nil {
		logger.L().Errorf("create k8s service json unmarshal failed:%v", req.ServiceJson)
		return fmt.Errorf("create k8s service json unmarshal failed:%v", req.ServiceJson)
	}

	_, err = g.Clientset.CoreV1().Services(g.Namespace).Create(c, service, metav1.CreateOptions{})
	if err != nil {
		if k8serrs.IsAlreadyExists(err) {
			logger.L().Infof("create k8s service already exists:%v", req.ServiceJson)
			return nil
		}
		logger.L().Errorf("create k8s service failed:%v", req.ServiceJson)
		return err
	}

	return nil
}

func (g *implK8s) DeleteService(c context.Context, req *DeleteServiceRequest) error {
	start := time.Now()
	defer func() {
		logger.L().Infof("%s elapsed K8SAPI_DeleteService:%v", req.Name, time.Since(start))
	}()
	if err := validate.V().Struct(req); err != nil {
		logger.L().Errorf("参数校验失败:%v", err)
		return fmt.Errorf("参数校验失败:%v", err)
	}
	deletePolicy := metav1.DeletePropagationBackground
	deleteOptions := metav1.DeleteOptions{
		PropagationPolicy: &deletePolicy,
	}

	err := g.CoreV1().Services(g.Namespace).Delete(c, req.Name, deleteOptions)
	if err != nil && (k8serrs.IsNotFound(err) || k8serrs.IsGone(err)) {
		logger.L().Infof("NOT Found as success:%v", err.Error())
		return nil
	}

	return err
}

func (g *implK8s) GetService(c context.Context, req *GetServiceRequest) (*corev1.Service, error) {
	start := time.Now()
	defer func() {
		logger.L().Infof("%s elapsed K8SAPI_GetService:%v", req.Name, time.Since(start))
	}()
	service, err := g.Clientset.CoreV1().Services(g.Namespace).Get(c, req.Name, metav1.GetOptions{})
	if err != nil {
		logger.L().Errorf("Failed to get service: %v", err)
		return nil, fmt.Errorf("failed to get service: %v", err)
	}
	return service, nil
}
